/*
 *  POJ3083: Children of the Candy Corn
 */

/*-------- Includes --------*/
#include <iostream>
#include <queue>

using namespace std;

/*-------- Types --------*/
struct Para {
    int x, y;   // coordinate
    int d;      // depth or direction
public:
    Para() {}
    Para(int xx, int yy, int dd) : x(xx), y(yy), d(dd) {}
};

/*-------- Global Variables --------*/

/*-------- Function Prototypes --------*/

/*-------- Main Function --------*/
int main(int argc, char const *argv[])
{
    int  nCase;         // number of cases
    int  h, w;          // height and width of maze
    bool maze[40][40];  // mark matrix
    Para S, E;          // start and exit
    char cstr[41];      // getline

    cin >> nCase;

    while (nCase--) {
        cin >> w >> h;

        // get maze
        for (int i = 0; i < h; i++) {
            cin >> cstr;

            for (int j = 0; j < w; j++) {
                switch (cstr[j]) {
                    case '#': maze[i][j] = false; break;
                    case '.': maze[i][j] = true;  break;
                    case 'S': S.x = i; S.y = j;   break;
                    case 'E': E.x = i; E.y = j;   break;
                    default:                      break;
                }
            }
        }

        maze[S.x][S.y] = true;
        maze[E.x][E.y] = true;

        Para par;

        /* DFS to find the left order path */
        par.x = S.x;
        par.y = S.y;

        if      (par.y == 0)     par.d = 0;
        else if (par.x == 0)     par.d = 1;
        else if (par.y + 1 == w) par.d = 2;
        else                     par.d = 3;

        int lcnt;
        for (lcnt = 1; par.x != E.x || par.y != E.y; lcnt++) {
            for (int i = 0; i < 4; i++) {
                bool OK = false;
                int  d  = (par.d + i) % 4;

                switch (d) {
                case 0:
                    if (par.x > 0 && maze[par.x - 1][par.y]) {
                        OK = true;
                        par.x--;
                        par.d = 3;
                    }
                    break;
                case 1:
                    if (par.y + 1 < w && maze[par.x][par.y + 1]) {
                        OK = true;
                        par.y++;
                        par.d = 0;
                    }
                    break;
                case 2:
                    if (par.x + 1 < h && maze[par.x + 1][par.y]) {
                        OK = true;
                        par.x++;
                        par.d = 1;
                    }
                    break;
                case 3:
                    if (par.y > 0 && maze[par.x][par.y - 1]) {
                        OK = true;
                        par.y--;
                        par.d = 2;
                    }
                    break;
                default:
                    break;
                }

                if (OK) break;
            }
        }

        /* DFS to find the right order path */
        par.x = S.x;
        par.y = S.y;

        if      (par.y + 1 == w) par.d = 0;
        else if (par.x + 1 == h) par.d = 1;
        else if (par.y == 0)     par.d = 2;
        else                     par.d = 3;

        int rcnt;
        for (rcnt = 1; par.x != E.x || par.y != E.y; rcnt++) {
            for (int i = 4; i >= 1; i--) {
                bool OK = false;
                int  d  = (par.d + i) % 4;

                switch (d) {
                case 0:
                    if (par.x > 0 && maze[par.x - 1][par.y]) {
                        OK = true;
                        par.x--;
                        par.d = 1;
                    }
                    break;
                case 1:
                    if (par.y + 1 < w && maze[par.x][par.y + 1]) {
                        OK = true;
                        par.y++;
                        par.d = 2;
                    }
                    break;
                case 2:
                    if (par.x + 1 < h && maze[par.x + 1][par.y]) {
                        OK = true;
                        par.x++;
                        par.d = 3;
                    }
                    break;
                case 3:
                    if (par.y > 0 && maze[par.x][par.y - 1]) {
                        OK = true;
                        par.y--;
                        par.d = 0;
                    }
                    break;
                default:
                    break;
                }

                if (OK) break;
            }
        }

        /* BFS to find the shortest path */
        queue<Para> que;

        // first element
        S.d = 1;
        que.push(S);
        maze[S.x][S.y] = false;

        // BFS
        while (!que.empty()) {
            par = que.front(); que.pop();

            // base case: find the exit
            if (par.x == E.x && par.y == E.y) break;

            // up
            if (par.x > 0 && maze[par.x - 1][par.y]) {
                que.push(Para(par.x - 1, par.y, par.d + 1));
                maze[par.x - 1][par.y] = false;
            }

            // down
            if (par.x + 1 < h && maze[par.x + 1][par.y]) {
                que.push(Para(par.x + 1, par.y, par.d + 1));
                maze[par.x + 1][par.y] = false;
            }

            // left
            if (par.y > 0 && maze[par.x][par.y - 1]) {
                que.push(Para(par.x, par.y - 1, par.d + 1));
                maze[par.x][par.y - 1] = false;
            }

            // right
            if (par.y + 1 < w && maze[par.x][par.y + 1]) {
                que.push(Para(par.x, par.y + 1, par.d + 1));
                maze[par.x][par.y + 1] = false;
            }
        }

        // print results
        cout << lcnt << " " << rcnt << " " << par.d << endl;
    }

    return 0;
}

/*-------- Functions --------*/

